GIO_PACKAGE=gio-unix-2.0
GDK_WINDOWING="$GDK_WINDOWING
#define GDK_WINDOWING_WAYLAND"
- WAYLAND_PACKAGES="wayland-client xkbcommon"
+ WAYLAND_PACKAGES="wayland-client xkbcommon wayland-egl"
AM_CONDITIONAL(USE_WAYLAND, true)
else
AM_CONDITIONAL(USE_WAYLAND, false)
gdkdisplaymanager-wayland.c \
gdkdnd-wayland.c \
gdkeventsource.c \
- gdkeventsource.h \
gdkkeys-wayland.c \
gdkscreen-wayland.c \
gdkscreen-wayland.h \
#include "gdkwayland.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <sys/mman.h>
+
#define GDK_TYPE_WAYLAND_CURSOR (_gdk_wayland_cursor_get_type ())
#define GDK_WAYLAND_CURSOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursor))
#define GDK_WAYLAND_CURSOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_WAYLAND_CURSOR, GdkWaylandCursorClass))
GdkCursor cursor;
gchar *name;
guint serial;
+ int x, y, width, height, size;
+ void *map;
+ struct wl_buffer *buffer;
};
struct _GdkWaylandCursorClass
return NULL;
}
+struct wl_buffer *
+_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, int *x, int *y)
+{
+ GdkWaylandCursor *wayland_cursor = GDK_WAYLAND_CURSOR (cursor);
+
+ *x = wayland_cursor->x;
+ *y = wayland_cursor->y;
+
+ return wayland_cursor->buffer;
+}
+
static void
_gdk_wayland_cursor_class_init (GdkWaylandCursorClass *wayland_cursor_class)
{
{
}
-GdkCursor*
-_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
- GdkCursorType cursor_type)
+static void
+set_pixbuf (GdkWaylandCursor *cursor, GdkPixbuf *pixbuf)
{
- GdkWaylandCursor *private;
+ int stride, i, n_channels;
+ unsigned char *pixels, *end, *argb_pixels, *s, *d;
+
+ stride = gdk_pixbuf_get_rowstride(pixbuf);
+ pixels = gdk_pixbuf_get_pixels(pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels(pixbuf);
+ argb_pixels = cursor->map;
+
+#define MULT(_d,c,a,t) \
+ do { t = c * a + 0x7f; _d = ((t >> 8) + t) >> 8; } while (0)
+
+ if (n_channels == 4)
+ {
+ for (i = 0; i < cursor->height; i++)
+ {
+ s = pixels + i * stride;
+ end = s + cursor->width * 4;
+ d = argb_pixels + i * cursor->width * 4;
+ while (s < end)
+ {
+ unsigned int t;
+
+ MULT(d[0], s[2], s[3], t);
+ MULT(d[1], s[1], s[3], t);
+ MULT(d[2], s[0], s[3], t);
+ d[3] = s[3];
+ s += 4;
+ d += 4;
+ }
+ }
+ }
+ else if (n_channels == 3)
+ {
+ for (i = 0; i < cursor->height; i++)
+ {
+ s = pixels + i * stride;
+ end = s + cursor->width * 3;
+ d = argb_pixels + i * cursor->width * 4;
+ while (s < end)
+ {
+ d[0] = s[2];
+ d[1] = s[1];
+ d[2] = s[0];
+ d[3] = 0xff;
+ s += 3;
+ d += 4;
+ }
+ }
+ }
+}
- private = g_object_new (GDK_TYPE_WAYLAND_CURSOR,
- "cursor-type", GDK_CURSOR_IS_PIXMAP,
- "display", display,
- NULL);
- private->name = NULL;
- private->serial = theme_serial;
+static GdkCursor *
+create_cursor(GdkDisplayWayland *display, GdkPixbuf *pixbuf, int x, int y)
+{
+ GdkWaylandCursor *cursor;
+ struct wl_visual *visual;
+ int stride, fd;
+ char *filename;
+ GError *error = NULL;
+
+ cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR,
+ "cursor-type", GDK_CURSOR_IS_PIXMAP,
+ "display", display,
+ NULL);
+ cursor->name = NULL;
+ cursor->serial = theme_serial;
+ cursor->x = x;
+ cursor->y = y;
+ cursor->width = gdk_pixbuf_get_width (pixbuf);
+ cursor->height = gdk_pixbuf_get_height (pixbuf);
+
+ stride = cursor->width * 4;
+ cursor->size = stride * cursor->height;
+
+ fd = g_file_open_tmp("wayland-shm-XXXXXX", &filename, &error);
+ if (fd < 0) {
+ fprintf(stderr, "g_file_open_tmp failed: %s\n", error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ unlink (filename);
+ g_free (filename);
+
+ if (ftruncate(fd, cursor->size) < 0) {
+ fprintf(stderr, "ftruncate failed: %m\n");
+ close(fd);
+ return NULL;
+ }
+
+ cursor->map = mmap(NULL, cursor->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cursor->map == MAP_FAILED) {
+ fprintf(stderr, "mmap failed: %m\n");
+ close(fd);
+ return NULL;
+ }
+
+ set_pixbuf (cursor, pixbuf);
+
+ visual = wl_display_get_premultiplied_argb_visual(display->wl_display);
+ cursor->buffer = wl_shm_create_buffer(display->shm,
+ fd,
+ cursor->width,
+ cursor->height,
+ stride, visual);
+
+ close(fd);
+
+ return GDK_CURSOR (cursor);
+}
- return GDK_CURSOR (private);
+#define DATADIR "/usr/share/wayland"
+
+static const struct {
+ GdkCursorType type;
+ const char *filename;
+ int hotspot_x, hotspot_y;
+} cursor_definitions[] = {
+ { GDK_XTERM, DATADIR "/xterm.png", 15, 15 },
+ { GDK_BOTTOM_RIGHT_CORNER, DATADIR "/bottom_right_corner.png", 28, 28 }
+};
+
+GdkCursor *
+_gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
+ GdkCursorType cursor_type)
+{
+ GdkDisplayWayland *wayland_display;
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (cursor_definitions); i++)
+ {
+ if (cursor_definitions[i].type == cursor_type)
+ break;
+ }
+
+ if (i == G_N_ELEMENTS (cursor_definitions))
+ return NULL;
+
+ wayland_display = GDK_DISPLAY_WAYLAND (display);
+ if (!wayland_display->cursors)
+ wayland_display->cursors =
+ g_new0 (GdkCursor *, G_N_ELEMENTS(cursor_definitions));
+ if (wayland_display->cursors[i])
+ return g_object_ref (wayland_display->cursors[i]);
+
+ pixbuf = gdk_pixbuf_new_from_file(cursor_definitions[i].filename, &error);
+ if (error != NULL)
+ {
+ g_error_free(error);
+ return NULL;
+ }
+
+ wayland_display->cursors[i] =
+ create_cursor(wayland_display, pixbuf,
+ cursor_definitions[i].hotspot_x,
+ cursor_definitions[i].hotspot_y);
+ g_object_unref (pixbuf);
+
+ return g_object_ref (wayland_display->cursors[i]);
}
GdkCursor*
GdkWindow *window,
GdkCursor *cursor)
{
+ GdkWaylandDevice *wd = GDK_DEVICE_CORE(device)->device;
+ struct wl_buffer *buffer;
+ int x, y;
+
+ if (cursor)
+ {
+ buffer = _gdk_wayland_cursor_get_buffer(cursor, &x, &y);
+ wl_input_device_attach(wd->device, wd->time, buffer, x, y);
+ }
+ else
+ {
+ wl_input_device_attach(wd->device, wd->time, NULL, 0, 0);
+ }
}
static void
GdkWindow *keyboard_focus;
struct wl_input_device *device;
int32_t x, y, surface_x, surface_y;
+ uint32_t time;
};
struct _GdkDeviceCore
#include "gdkdevice-wayland.h"
#include "gdkkeysyms.h"
#include "gdkprivate-wayland.h"
-#include "gdkeventsource.h"
#include <X11/extensions/XKBcommon.h>
+#include <X11/keysym.h>
static void gdk_device_manager_core_finalize (GObject *object);
event = gdk_event_new (GDK_NOTHING);
+ device->time = time;
device->x = x;
device->y = y;
device->surface_x = sx;
fprintf (stderr, "button event %d, state %d\n", button, state);
+ device->time = time;
event = gdk_event_new (state ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE);
event->button.window = g_object_ref (device->pointer_focus);
gdk_event_set_device (event, device->pointer);
struct xkb_desc *xkb;
GdkKeymap *keymap;
+ device->time = time;
event = gdk_event_new (state ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
event->key.window = g_object_ref (device->keyboard_focus);
gdk_event_set_device (event, device->keyboard);
code = key + xkb->min_key_code;
level = 0;
- if (device->modifiers & ShiftMask &&
+ if (device->modifiers & XKB_COMMON_SHIFT_MASK &&
XkbKeyGroupWidth(xkb, code, 0) > 1)
level = 1;
GdkWaylandDevice *device = data;
GdkEvent *event;
+ device->time = time;
if (device->pointer_focus)
{
event = gdk_event_new (GDK_LEAVE_NOTIFY);
fprintf (stderr, "keyboard focus surface %p\n", surface);
+ device->time = time;
if (device->keyboard_focus)
{
event = gdk_event_new (GDK_FOCUS_CHANGE);
* Boston, MA 02111-1307, USA.
*/
-#define EGL_EGLEXT_PROTOTYPES 1
-
#include "config.h"
+#include <wayland-egl.h>
+
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "gdkwayland.h"
#include "gdkdisplay.h"
#include "gdkdisplay-wayland.h"
-#include "gdkeventsource.h"
#include "gdkscreen.h"
#include "gdkscreen-wayland.h"
#include "gdkinternals.h"
#include "gdkdevicemanager-wayland.h"
#include "gdkkeysprivate.h"
-#include <wayland-egl.h>
-
typedef struct _GdkEventTypeWayland GdkEventTypeWayland;
struct _GdkEventTypeWayland
if (strcmp(interface, "compositor") == 0) {
display_wayland->compositor = wl_compositor_create(display, id);
+ } else if (strcmp(interface, "shm") == 0) {
+ display_wayland->shm = wl_shm_create(display, id);
} else if (strcmp(interface, "shell") == 0) {
display_wayland->shell = wl_shell_create(display, id);
wl_shell_add_listener(display_wayland->shell,
};
display_wayland->egl_display =
- eglGetDisplay((EGLNativeDisplayType) display_wayland->native_display);
+ eglGetDisplay(display_wayland->native_display);
if (!eglInitialize(display_wayland->egl_display, &major, &minor)) {
fprintf(stderr, "failed to initialize display\n");
return FALSE;
gdk_input_init (display);
g_signal_emit_by_name (display, "opened");
- g_signal_emit_by_name (gdk_display_manager_get(),
- "display_opened", display);
+ g_signal_emit_by_name (gdk_display_manager_get(), "display_opened", display);
return display;
}
if (display_wayland->keymap)
g_object_unref (display_wayland->keymap);
- /* Atom Hashtable */
- g_hash_table_destroy (display_wayland->atom_from_virtual);
- g_hash_table_destroy (display_wayland->atom_to_virtual);
-
- /* list of filters for client messages */
- g_list_foreach (display_wayland->client_filters, (GFunc) g_free, NULL);
- g_list_free (display_wayland->client_filters);
-
- /* List of event window extraction functions */
- g_slist_foreach (display_wayland->event_types, (GFunc)g_free, NULL);
- g_slist_free (display_wayland->event_types);
-
/* input GdkDevice list */
g_list_foreach (display_wayland->input_devices, (GFunc) g_object_unref, NULL);
g_list_free (display_wayland->input_devices);
g_free (display_wayland->startup_notification_id);
- /* X ID hashtable */
- g_hash_table_destroy (display_wayland->xid_ht);
-
G_OBJECT_CLASS (_gdk_display_wayland_parent_class)->finalize (object);
}
static gboolean
gdk_wayland_display_supports_selection_notification (GdkDisplay *display)
{
- GdkDisplayWayland *display_wayland = GDK_DISPLAY_WAYLAND (display);
-
- return display_wayland->have_xfixes;
+ return TRUE;
}
static gboolean
static gboolean
gdk_wayland_display_supports_shapes (GdkDisplay *display)
{
- return GDK_DISPLAY_WAYLAND (display)->have_shapes;
+ return TRUE;
}
static gboolean
gdk_wayland_display_supports_input_shapes (GdkDisplay *display)
{
- return GDK_DISPLAY_WAYLAND (display)->have_input_shapes;
+ return TRUE;
}
static gboolean
#include <stdint.h>
#include <wayland-client.h>
+#include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>
gint grab_count;
/* Keyboard related information */
-
- gint xkb_event_type;
- gboolean use_xkb;
-
- /* Whether we were able to turn on detectable-autorepeat using
- * XkbSetDetectableAutorepeat. If FALSE, we'll fall back
- * to checking the next event with XPending(). */
- gboolean have_xkb_autorepeat;
-
GdkKeymap *keymap;
guint keymap_serial;
- gboolean have_xfixes;
- gint xfixes_event_base;
-
- gboolean have_xcomposite;
- gboolean have_xdamage;
- gint xdamage_event_base;
-
- gboolean have_randr13;
- gint xrandr_event_base;
-
- /* If the SECURITY extension is in place, whether this client holds
- * a trusted authorization and so is allowed to make various requests
- * (grabs, properties etc.) Otherwise always TRUE. */
- gboolean trusted_client;
-
/* drag and drop information */
GdkDragContext *current_dest_drag;
- /* data needed for MOTIF DnD */
-
- Window motif_drag_window;
- GdkWindow *motif_drag_gdk_window;
- GList **motif_target_lists;
- gint motif_n_target_lists;
-
- /* Mapping to/from virtual atoms */
-
- GHashTable *atom_from_virtual;
- GHashTable *atom_to_virtual;
-
- /* list of filters for client messages */
- GList *client_filters;
-
- /* List of functions to go from extension event => X window */
- GSList *event_types;
-
- /* X ID hashtable */
- GHashTable *xid_ht;
-
- /* translation queue */
- GQueue *translate_queue;
-
- /* Input device */
/* input GdkDevice list */
GList *input_devices;
/* Time of most recent user interaction. */
gulong user_time;
- /* Sets of atoms for DND */
- guint base_dnd_atoms_precached : 1;
- guint xdnd_atoms_precached : 1;
- guint motif_atoms_precached : 1;
- guint use_sync : 1;
-
- guint have_shapes : 1;
- guint have_input_shapes : 1;
- gint shape_event_base;
-
/* The offscreen window that has the pointer in it (if any) */
GdkWindow *active_offscreen_window;
struct wl_display *wl_display;
struct wl_egl_display *native_display;
struct wl_compositor *compositor;
+ struct wl_shm *shm;
struct wl_shell *shell;
struct wl_output *output;
struct wl_input_device *input_device;
EGLContext egl_context;
cairo_device_t *cairo_device;
+ GdkCursor **cursors;
+
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d;
PFNEGLCREATEIMAGEKHRPROC create_image;
PFNEGLDESTROYIMAGEKHRPROC destroy_image;
};
GType _gdk_display_wayland_get_type (void);
-GdkScreen *_gdk_wayland_display_screen_for_xrootwin (GdkDisplay *display,
- Window xrootwin);
G_END_DECLS
#include "config.h"
-#include "gdkeventsource.h"
#include "gdkinternals.h"
+#include "gdkprivate-wayland.h"
typedef struct _GdkWaylandEventSource {
GSource source;
+++ /dev/null
-/* GDK - The GIMP Drawing Kit
- * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GDK_EVENT_SOURCE_H__
-#define __GDK_EVENT_SOURCE_H__
-
-#include "gdkprivate-wayland.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GdkEventSource GdkEventSource;
-
-G_GNUC_INTERNAL
-GSource * gdk_event_source_new (GdkDisplay *display);
-
-G_GNUC_INTERNAL
-void gdk_event_source_select_events (GdkEventSource *source,
- Window window,
- GdkEventMask event_mask,
- unsigned int extra_x_mask);
-
-G_GNUC_INTERNAL
-void _gdk_deliver_event (GdkDisplay *display, GdkEvent *event);
-
-
-G_END_DECLS
-
-#endif /* __GDK_EVENT_SOURCE_H__ */
gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display);
gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display);
+struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkCursor *cursor,
+ int *x,
+ int *y);
+
GdkDragProtocol _gdk_wayland_window_get_drag_protocol (GdkWindow *window,
GdkWindow **target);
int width_mm, height_mm;
/* Window manager */
- long last_wmspec_check_time;
- Window wmspec_check_window;
char *window_manager_name;
/* TRUE if wmspec_check_window has changed since last
* fetch of _NET_SUPPORTED
struct _GdkWaylandMonitor
{
GdkRectangle geometry;
- XID output;
int width_mm;
int height_mm;
char * output_name;
monitor->geometry.width = width;
monitor->geometry.height = height;
- monitor->output = None;
monitor->width_mm = -1;
monitor->height_mm = -1;
monitor->output_name = NULL;
_gdk_window_destroy (screen_wayland->root_window, TRUE);
G_OBJECT_CLASS (_gdk_screen_wayland_parent_class)->dispose (object);
-
- screen_wayland->wmspec_check_window = None;
}
static void
screen_wayland = GDK_SCREEN_WAYLAND (screen);
screen_wayland->display = display;
- screen_wayland->wmspec_check_window = None;
/* we want this to be always non-null */
screen_wayland->window_manager_name = g_strdup ("unknown");
#include "gdkwindow-wayland.h"
#include "gdkdeviceprivate.h"
#include "gdkdevice-wayland.h"
-#include "gdkeventsource.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <wayland-client.h>
+#include <wayland-egl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GL/gl.h>
/* Time of most recent user interaction. */
gulong user_time;
-
- /* We use an extra X window for toplevel windows that we XSetInputFocus()
- * to in order to avoid getting keyboard events redirected to subwindows
- * that might not even be part of this app
- */
- Window focus_window;
};
GType _gdk_window_impl_wayland_get_type (void);